/*
 * Created by JFormDesigner on Tue Jul 13 18:38:50 CST 2021
 */

package com.minelx.statementplus.ui.form.ui.memberbased.addingfield;

import com.alibaba.fastjson.JSON;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.minelx.sqlstructures.core.database.IDatabase;
import com.minelx.sqlstructures.core.database.JsonDatabase;
import com.minelx.sqlstructures.core.table.ITable;
import com.minelx.sqlstructures.core.values.FieldValues;
import com.minelx.statementplus.ui.form.dao.TableAndFieldValuesListModel;
import com.minelx.statementplus.ui.form.service.tablemapping.ITableMapping;
import com.minelx.statementplus.ui.form.swing.DatabaseToNode;
import com.minelx.statementplus.ui.form.swing.DialogInputs;
import com.minelx.statementplus.ui.form.swing.OnClosingDialog;
import com.minelx.util.Files;
import com.minelx.woods.task.core.values.FieldPathValues;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @author aaa
 */
public class AddingFieldDialog extends OnClosingDialog {

	private final TableAndFieldValuesListModel tableAndFieldValuesListModel;

	public AddingFieldDialog(Window owner,
							 TableAndFieldValuesListModel tableAndFieldValuesListModel,
							 ITableMapping tableMapping) {
		super(owner, e -> {
		});
		initComponents();
		this.tableAndFieldValuesListModel = tableAndFieldValuesListModel;

		JsonDatabase database = remoteDatabase();

		// FIXME 2021/8/21  THIS METHOD NEEDED TEST SUPPORT!
		DefaultMutableTreeNode remoteDatabase = new DatabaseToNode().toNode(new LimitedDatabase(database, tableMapping.fieldTables()));
		tree.setModel(new DefaultTreeModel(remoteDatabase));
		setCellRendererForTree();
		bindTreeSelectionListener();
		setCellRendererForResultList();

		resultList.setModel(tableAndFieldValuesListModel);
	}

	private void deleteSelectionButtonActionPerformed(ActionEvent e) {
		tableAndFieldValuesListModel.removeElement(resultList.getSelectedIndex());
	}

	private void deleteAllFieldsButtonActionPerformed(ActionEvent e) {
		tableAndFieldValuesListModel.clear();
	}

	void bindTreeSelectionListener() {
		tree.addTreeSelectionListener(e -> {
			TreePath treePath = e.getPath();
			if (treePath.getPathCount() == 3) { // leaf node
				FieldPathValues addedFieldPathValues = DatabasePath.create(treePath).createValue();
				if (!tableAndFieldValuesListModel.contains(addedFieldPathValues)) {
					if (tableAndFieldValuesListModel.toList().stream()
							.noneMatch(which -> which.getComment().equals(addedFieldPathValues.getComment()))) {
						tableAndFieldValuesListModel.addElement(addedFieldPathValues);
						return;
					}
					tableAndFieldValuesListModel.addElement(new FieldPathValues(
							addedFieldPathValues.getTableName(),
							addedFieldPathValues.getFieldName(),
							DialogInputs.candyOrJoke(this, "重复名称, 输入别名: ")));
				}
			}
		});
	}

	void setCellRendererForTree() {
		TreeCellRenderer defaultRenderer = tree.getCellRenderer();
		tree.setCellRenderer((tree, value, selected, expanded, leaf, row, hasFocus) ->
		{
			DatabaseToNode.NodeAdapter adapter = (DatabaseToNode.NodeAdapter) ((DefaultMutableTreeNode) value).getUserObject();
			return defaultRenderer.getTreeCellRendererComponent(tree, commentOf(adapter.get()), selected, expanded, leaf, row, hasFocus);
		});
	}

	void setCellRendererForResultList() {
		ListCellRenderer defaultResultListRenderer = resultList.getCellRenderer();
		resultList.setCellRenderer((list, value, index, isSelected, cellHasFocus) -> {
			FieldPathValues tableAndField = (FieldPathValues) value;
			String content = tableAndField.getTableName() + " -> " + tableAndField.getFieldName();
			return defaultResultListRenderer.getListCellRendererComponent(list, content, index, isSelected, cellHasFocus);
		});
	}

	// FIXME 2021/7/14  wait for me!!!     to literal-depends only
	// FIXME 2021/7/4  wait for me!!!

	static String commentOf(Object userObject) {
		if (userObject instanceof IDatabase) {
			return ((IDatabase) userObject).getName();
		} else if (userObject instanceof ITable) {
			return ((ITable) userObject).getName();
		} else if (userObject instanceof FieldValues) {
			FieldValues fieldDTO = (FieldValues) userObject;
			if (fieldDTO.getComment().isEmpty()) {
				return fieldDTO.getName();
			}
			return fieldDTO.getComment();
		} else {
			throw new RuntimeException("operation is unsupported." + userObject);
		}
	}

	public static JsonDatabase remoteDatabase() {
		return new JsonDatabase(JSON.parseObject(Files.toString(Objects.requireNonNull(AddingFieldDialog.class.getResourceAsStream("/remote_database.json")), StandardCharsets.UTF_8)));
	}

	private void initComponents() {
		// JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
		scrollPane1 = new JScrollPane();
		tree = new JTree();
		scrollPane2 = new JScrollPane();
		resultList = new JList();
		panel1 = new JPanel();
		deleteSelectionButton = new JButton();
		deleteAllFieldsButton = new JButton();

		//======== this ========
		setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		var contentPane = getContentPane();
		contentPane.setLayout(new GridLayoutManager(2, 2, new Insets(0, 0, 0, 0), 5, -1));

		//======== scrollPane1 ========
		{

			//---- tree ----
			tree.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 17));
			scrollPane1.setViewportView(tree);
		}
		contentPane.add(scrollPane1, new GridConstraints(0, 0, 1, 1,
				GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
				null, null, null));

		//======== scrollPane2 ========
		{

			//---- resultList ----
			resultList.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 17));
			scrollPane2.setViewportView(resultList);
		}
		contentPane.add(scrollPane2, new GridConstraints(0, 1, 1, 1,
				GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
				null, null, null));

		//======== panel1 ========
		{
			panel1.setLayout(new FlowLayout());

			//---- deleteSelectionButton ----
			deleteSelectionButton.setText("\u5220\u9664\u9009\u4e2d");
			deleteSelectionButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 24));
			deleteSelectionButton.addActionListener(e -> deleteSelectionButtonActionPerformed(e));
			panel1.add(deleteSelectionButton);

			//---- deleteAllFieldsButton ----
			deleteAllFieldsButton.setText("\u6e05\u7a7a");
			deleteAllFieldsButton.setFont(new Font("Microsoft JhengHei Light", Font.PLAIN, 24));
			deleteAllFieldsButton.addActionListener(e -> deleteAllFieldsButtonActionPerformed(e));
			panel1.add(deleteAllFieldsButton);
		}
		contentPane.add(panel1, new GridConstraints(1, 1, 1, 1,
				GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE,
				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
				GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
				null, null, null));
		setSize(940, 705);
		setLocationRelativeTo(getOwner());
		// JFormDesigner - End of component initialization  //GEN-END:initComponents
	}

	// JFormDesigner - Variables declaration - DO NOT MODIFY  //GEN-BEGIN:variables
	private JScrollPane scrollPane1;
	private JTree tree;
	private JScrollPane scrollPane2;
	private JList resultList;
	private JPanel panel1;
	private JButton deleteSelectionButton;
	private JButton deleteAllFieldsButton;
	// JFormDesigner - End of variables declaration  //GEN-END:variables
}